import numpy

def get_pcs(stars,numpc=100):
    """Represents stars in the principal component space."""
    phases = numpy.linspace(0,0.99,numpc)
    lightcurves = numpy.array([poly_eval(phases,star.coefficients) for star in stars])
    normalized = numpy.array([lightcurves[i]-lightcurves[i].mean() for i in range(len(lightcurves))])
    subcoeff,subscore,sublatent=princomp(normalized,numpc=numpc)
    return subscore

def save_pcs(stars,pcs,filename,delimiter=' '):
    """Saves the mode, period, and principal components for the given stars."""
    file=open(filename,"w")
    for i in range(len(stars)):
        file.write(str(stars[i].mode)+delimiter+str(stars[i].period))
        for j in range(len(pcs.T[i])):
            file.write(delimiter+str(pcs.T[i][j].real))
        file.write("\n")
    file.close()

def get_bins(vals,bin_size=1):
    """Creates and places values into bins for every column in the data."""
    bins = [[int(math.floor((val-vals.T[i].mean())/(vals.T[i].std()*bin_size))) for val
             in vals.T[i]] for i
            in range(len(vals.T))]
    return numpy.array(bins).T

def save_bins(writefile,openfile,bin_size=1/4.):
    """Saves the bins to a file."""
    vals = numpy.fromfile(openfile,dtype=float,sep='\n').reshape(-1,102)
    numpy.savetxt(writefile,get_bins(vals,bin_size=bin_size),fmt='%i')

def princomp(A,numpc=0):
    """http://glowingpython.blogspot.it/2011/07/pca-and-image-compression-with-numpy.html"""
    from numpy import mean,cov,cumsum,dot,linalg,size,flipud,argsort
    # computing eigenvalues and eigenvectors of covariance matrix
    M = (A-mean(A.T,axis=1)).T # subtract the mean (along columns)
    [latent,coeff] = linalg.eig(cov(M))
    p = size(coeff,axis=1)
    idx = argsort(latent) # sorting the eigenvalues
    idx = idx[::-1]       # in ascending order
    # sorting eigenvectors according to the sorted eigenvalues
    coeff = coeff[:,idx]
    latent = latent[idx] # sorting eigenvalues
    if numpc < p or numpc >= 0:
        coeff = coeff[:,range(numpc)] # cutting some PCs
    score = dot(coeff.T,M) # projection of the data in the new space
    return coeff,score,latent

